﻿using GeneticAlgorithms.Genomes;
using GeneticAlgorithms.Tools;

namespace GeneticAlgorithms.Operators.Crossover
{
    /// <summary>
    /// Implements two-point crossover.
    /// </summary>
    /// <typeparam name="TGenome">The type of the genome.</typeparam>
    /// <typeparam name="TGene">The type of the gene.</typeparam>
    public class DoublePointCrossover<TGenome, TGene> : BaseCrossoverOperator<TGenome, TGene>
        where TGenome : IGenome<TGene>
    {
        private int cutPoint1;

        private int cutPoint2;

        /// <summary>
        /// Determines whether a switch should happen in the specified position.
        /// </summary>
        /// <param name="currentPos">The current position.</param>
        /// <returns>
        /// 	<c>true</c> in case the operator should switch the
        /// order in which it is copying genes, <c>false</c>
        /// otherwise.
        /// </returns>
        protected override bool ShouldSwitch(int currentPos)
        {
            return currentPos == cutPoint1 || currentPos == cutPoint2;
        }

        /// <summary>
        /// Initializes the two cut points for the crossover operation.
        /// </summary>
        /// <param name="maximumIndex">The maxValue allowed index inside the genomes.</param>
        protected override void Init(int maximumIndex)
        {
            cutPoint1 = GeneticRandomGenerator.Default.Next(maximumIndex);
            cutPoint2 = GeneticRandomGenerator.Default.Next(maximumIndex);
        }
    }
}
